package com.rzico.sbl.ui.report.invite

import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import com.google.gson.Gson
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lzg.extend.jackson.JsonUtil
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityReportInviteEditBinding
import com.rzico.sbl.model.DispatchBucket
import com.rzico.sbl.model.DispatchRotten
import com.rzico.sbl.model.ReportGoodsData
import com.rzico.sbl.ui.report.other.ReportUrl
import com.rzico.sbl.viewmodel.ReportInviteViewModel
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.*
import com.xinnuo.common.listener._TextWatcher
import com.xinnuo.common.view.FullyLinearLayoutManager
import com.xinnuo.common.decoration.SpaceTBDecoration
import com.xinnuo.common.other.DecimalNumberFilter
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.base.addItems
import com.xinnuo.common_ui.utils.*
import com.xinnuo.slimadapter.SlimAdapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.cachapa.expandablelayout.ExpandableLayout
import org.json.JSONArray
import org.json.JSONObject

class ReportInviteEditActivity : BaseActivity(R.layout.activity_report_invite_edit) {

    private val mBinding by lazy { ActivityReportInviteEditBinding.bind(getRootView()) }

    private lateinit var mBarrelAdapter: SlimAdapter
    private lateinit var mRottenAdapter: SlimAdapter
    private var mShopId = ""
    private var mInviteId = ""
    private val mBarrelList = arrayListOf<DispatchBucket>()
    private val mEditList = arrayListOf<DispatchBucket>()
    private val mRottenList = arrayListOf<DispatchRotten>()

    override fun getViewModel() = get<ReportInviteViewModel>()

    override fun initData() {
        initTitle(title = "入空桶编辑")

        initBarrelLayout()
        initRottenLayout()

        mBarrelAdapter.setDataList(mEditList)
        mRottenAdapter.setDataList(mRottenList)

        getData()
        mInviteId.notEmpty {
            getInviteDetail()
        }
    }

    private fun initBarrelLayout() {
        mBinding
            .barrelList
            .apply {
                isNestedScrollingEnabled = false
                layoutManager = FullyLinearLayoutManager(baseContext)

                addItemDecoration(SpaceTBDecoration(hasHeader = false, hasFooter = false))

                mBarrelAdapter = SlimAdapter.creator()
                    .register<DispatchBucket>(R.layout.item_report_invite_bucket) { jector, bean, index ->
                        jector.apply {
                            text(R.id.item_bucket_barrel, bean.name) //品牌
                            text(R.id.item_bucket_change, bean.transQuantity.orEmpty("0")) //兑换桶
                            text(R.id.item_bucket_total, bean.returnQuantity.orEmpty("0")) //总入库

                            // 入库
                            with<EditText>(R.id.item_bucket_in) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.clear()
                                bean.memo2.notEmpty {
                                    it.setText(this)
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.memo2 = s.toString()

                                        // 计算总入库数
                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_total)
                                                .text = bean.returnQuantity
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 外品牌1:1
                            with<EditText>(R.id.item_bucket_one) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.clear()
                                bean.percent1.notEmpty {
                                    it.setText(this)
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.percent1 = s.toString()

                                        // 计算兑换数和总入库数
                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_change)
                                                .text = bean.transQuantity
                                            getView<TextView>(R.id.item_bucket_total)
                                                .text = bean.returnQuantity
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 外品牌2:1
                            with<EditText>(R.id.item_bucket_two) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.clear()
                                bean.percent2.notEmpty {
                                    it.setText(this)
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.percent2 = s.toString()

                                        // 计算兑换数和总入库数
                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_change)
                                                .text = bean.transQuantity
                                            getView<TextView>(R.id.item_bucket_total)
                                                .text = bean.returnQuantity
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 外品牌3:1
                            with<EditText>(R.id.item_bucket_three) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.clear()
                                bean.percent3.notEmpty {
                                    it.setText(this)
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.percent3 = s.toString()

                                        // 计算兑换数和总入库数
                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_change)
                                                .text = bean.transQuantity
                                            getView<TextView>(R.id.item_bucket_total)
                                                .text = bean.returnQuantity
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 外品牌补差价
                            with<EditText>(R.id.item_bucket_fill) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.clear()
                                bean.percent4.notEmpty {
                                    it.setText(this)
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.percent4 = s.toString()

                                        // 计算兑换数和总入库数
                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_change)
                                                .text = bean.transQuantity
                                            getView<TextView>(R.id.item_bucket_total)
                                                .text = bean.returnQuantity
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 补差价金额
                            with<EditText>(R.id.item_bucket_money) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.clear()
                                it.filters =
                                    arrayOf(DecimalNumberFilter(), InputFilter.LengthFilter(8))

                                bean.differPrice.notEmpty {
                                    it.setText(this.formatDecimal())
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.differPrice = s.toString()
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            clicked(R.id.item_bucket_del) {
                                mEditList.removeAt(index)
                                notifyDataSetChanged()
                            }

                            clicked(R.id.item_bucket_change_ll) {
                                val expand = getView<ExpandableLayout>(R.id.item_bucket_expand)
                                val arrow = getView<ImageView>(R.id.item_bucket_change_arrow)

                                if (expand.isExpanded) {
                                    expand.collapse()
                                    arrow.startRotateAnimator(90f, 0f)
                                } else {
                                    expand.expand()
                                    arrow.startRotateAnimator(0f, 90f)
                                }
                            }
                        }
                    }
                    .attachTo(this)
            }
    }

    private fun initRottenLayout() {
        mBinding
            .rottenList
            .apply {
                isNestedScrollingEnabled = false
                layoutManager = FullyLinearLayoutManager(baseContext)

                addItemDecoration(SpaceTBDecoration(hasHeader = false, hasFooter = false))

                mRottenAdapter = SlimAdapter.creator()
                    .register<DispatchRotten>(R.layout.item_report_invite_rotten) { jector, bean, index ->
                        jector.apply {
                            text(
                                R.id.item_rotten_name,
                                "${bean.name}(${bean.phBarrelName})"
                            )
                            text(R.id.item_rotten_price, bean.price.formatDecimal())
                            text(R.id.item_rotten_amount, bean.subPrice.formatDecimal())

                            // 烂桶数量
                            with<EditText>(R.id.item_rotten_count) { edit ->
                                if (edit.tag != null && edit.tag is TextWatcher) {
                                    edit.removeTextChangedListener(edit.tag as TextWatcher)
                                }

                                edit.clear()
                                bean.quantity.notEmpty {
                                    edit.setText(this)
                                    edit.setSelection(edit.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.quantity = s.toString()

                                        // 计算烂桶总金额
                                        bean.subPrice =
                                            (bean.quantity.intValue * bean.price.doubleValue)
                                                .formatDecimal()
                                        getView<TextView>(R.id.item_rotten_amount)
                                            .text = bean.subPrice

                                        // 判断烂桶数是否大于入库数
                                        val inputSum = mRottenList
                                            .filter { it.phBarrelId == bean.phBarrelId }
                                            .sumOf { it.quantity.intValue }

                                        mEditList
                                            .firstOrNull { it.id == bean.phBarrelId }
                                            ?.let {
                                                if (it.memo2.intValue < inputSum) {
                                                    it.memo2 = inputSum.toString()
                                                    calculateItem(it) {
                                                        mBarrelAdapter.notifyDataSetChanged()
                                                    }
                                                }
                                            }
                                    }
                                }
                                edit.addTextChangedListener(textWatcher)
                                edit.tag = textWatcher
                            }

                            clicked(R.id.item_rotten_del) {
                                mRottenList.removeAt(index)
                                notifyDataSetChanged()
                            }
                        }
                    }
                    .attachTo(this)
            }
    }

    override fun initListener() {
        mBinding.apply {
            mShopId = intent.getExtra("shopId")
            mInviteId = intent.getExtra("inviteId")
            inviteTitle.text = intent.getExtra("shopName")

            inviteBarrel.oneClick {
                if (mBarrelList.isEmpty()) {
                    showToast("获取品牌信息失败！")
                    return@oneClick
                }

                showLoopDialog()
            }

            inviteRotten.oneClick {
                startActivityEx<ReportInviteGoodsActivity>(
                    "shopId" to mShopId
                )
            }

            inviteSave.oneClick {
                when {
                    mEditList.isEmpty() -> {
                        showToast("请添加入库品牌")
                        return@oneClick
                    }
                    mEditList.any { it.returnQuantity.intValue == 0 } -> {
                        showToast("请输入品牌入库数")
                        return@oneClick
                    }
                    mEditList.any { it.percent2.intValue % 2 != 0 } -> {
                        showToast("外品牌2:1 只能输入2的倍数")
                        return@oneClick
                    }
                    mEditList.any { it.percent3.intValue % 3 != 0 } -> {
                        showToast("外品牌3:1 只能输入3的倍数")
                        return@oneClick
                    }
                    mEditList.any {
                        !it.percent4.isNullOrEmpty()
                                && it.differPrice.isNullOrEmpty()
                    } -> {
                        showToast("请检查外品牌补差价金额")
                        return@oneClick
                    }
                    mRottenList.any { it.quantity.intValue == 0 } -> {
                        showToast("请输入烂桶数量")
                        return@oneClick
                    }
                }

                // 计算烂桶
                mEditList.forEach { item ->
                    val inputSum = mRottenList
                        .filter { it.phBarrelId == item.id }
                        .sumOf { it.quantity.intValue }

                    if (inputSum > item.memo2.intValue) {
                        showToast("入库(含烂桶)不能小于烂桶数量")
                        return@oneClick
                    }

                    item.swapQuantity = inputSum.toString()
                }

                // 判断补差价
                mEditList
                    .filter { !it.differPrice.isNullOrEmpty() }
                    .forEach {
                        if (it.percent4.isNullOrEmpty()) it.differPrice = ""
                    }

                val barrelAmount = mEditList.sumOf { it.differPrice.doubleValue }
                val rottenAmount = mRottenList.sumOf { it.subPrice.doubleValue }

                val jsonObj = JSONObject().apply {
                    put(
                        "barrels",
                        JSONArray(Gson().toJson(mEditList.filter { it.returnQuantity.intValue > 0 }))
                    )
                    put(
                        "swaps",
                        JSONArray(Gson().toJson(mRottenList.filter { it.quantity.intValue > 0 }))
                    )
                }

                getViewModel()
                    .inviteSave(
                        url = when {
                            mInviteId.isEmpty() -> ReportUrl.getBaseUrl().inviteSave
                            else -> ReportUrl.getBaseUrl().inviteUde
                        },
                        "id" to mInviteId.ifEmpty { mShopId },
                        "barrelPrice" to barrelAmount,
                        "swapPrice" to rottenAmount,
                        "body" to jsonObj.toString(),
                        "memo" to inviteMemo.content
                    )
                    .bindLifeCycle(getLifecycleOwner())
                    .subscribeBySuccess(
                        event = getViewModel(),
                        onSuccess = {
                            showToast("保存信息成功！")

                            // 刷新入空桶列表
                            LiveEventBus
                                .get("inviteList")
                                .post("refresh")

                            ActivityStack.screenManager.popActivities(
                                ReportInviteEditActivity::class.java,
                                ReportInviteStationActivity::class.java
                            )
                        }
                    )
            }
        }

        LiveEventBus
            .get("inviteGoods", ReportGoodsData::class.java)
            .observe(this) { item ->
                getViewModel()
                    .delay {
                        if (mRottenList.none { it.id == item.productId }) {
                            if (mEditList.none { it.id == item.phBarrelId }) {
                                val barrel = mBarrelList.firstOrNull { it.id == item.phBarrelId }
                                if (barrel != null) {
                                    mEditList.add(
                                        DispatchBucket(
                                            id = barrel.id,
                                            name = barrel.name,
                                            price = barrel.price
                                        )
                                    )

                                    mRottenList.add(
                                        DispatchRotten(
                                            id = item.productId.orEmpty(),
                                            name = item.name,
                                            price = item.phPrice.orEmpty("0.00"),
                                            phBarrelId = item.phBarrelId.orEmpty(),
                                            phBarrelName = item.phBarrelName.orEmpty()
                                        )
                                    )

                                    mBarrelAdapter.notifyDataSetChanged()
                                    mRottenAdapter.notifyDataSetChanged()
                                } else
                                    showToast("暂无该品牌，请联系管理员")
                            } else {
                                mRottenList.add(
                                    DispatchRotten(
                                        id = item.productId.orEmpty(),
                                        name = item.name,
                                        price = item.phPrice.orEmpty("0.00"),
                                        phBarrelId = item.phBarrelId.orEmpty(),
                                        phBarrelName = item.phBarrelName.orEmpty()
                                    )
                                )

                                mRottenAdapter.notifyDataSetChanged()
                            }
                        } else
                            showToast("已存在该商品，请添加其他商品")
                    }
            }
    }

    /**
     * 添加回桶品牌弹框
     */
    private fun showLoopDialog() {
        val items = mBarrelList.filter {
            mEditList.none { item ->
                item.id == it.id
            }
        }

        items.isNotEmpty()
            .conditionElse(
                actionTrue = {
                    showListDialog(
                        title = "请选择品牌",
                        items = items.map { it.name.orEmpty() },
                        listener = { index, _ ->
                            val item = items[index]
                            mEditList.add(
                                DispatchBucket(
                                    id = item.id,
                                    name = item.name,
                                    price = item.price
                                )
                            )
                            mBarrelAdapter.notifyDataSetChanged()
                        }
                    )
                },
                actionFalse = { showToast("暂无其他品牌系列") }
            )
    }

    /**
     * 兑换桶，总入库计算
     */
    private fun calculateItem(bean: DispatchBucket, onNext: () -> Unit) =
        lifecycleScope.launch(Dispatchers.IO) {
            val countIn = bean.memo2.intValue
            val countOne = bean.percent1.intValue
            val countTwo = bean.percent2.intValue / 2
            val ocountThree = bean.percent3.intValue / 3
            val ocountFill = bean.percent4.intValue

            bean.transQuantity =
                (countOne
                        + countTwo
                        + ocountThree
                        + ocountFill).toString()

            bean.returnQuantity =
                (bean.transQuantity.intValue
                        + countIn).toString()

            withContext(Dispatchers.Main) { onNext.invoke() }
        }

    /**
     * 空桶品牌列表
     */
    override fun getData(index: Int, isLoading: Boolean) {
        getViewModel()
            .barrelList(mShopId)
            .bindLifeCycle(getLifecycleOwner())
            .subscribeByFinally(
                event = getViewModel(),
                onSuccess = { value ->
                    mBarrelList.clear()
                    mBarrelList.addItems(value)

                    // 计算入库数
                    mBarrelList.forEach {
                        val count =
                            (it.returnQuantity.intValue
                                    - it.transQuantity.intValue)

                        if (count > 0) it.memo2 = count.toString()
                    }
                }
            )
    }

    /**
     * 入空桶详情
     */
    private fun getInviteDetail() {
        getViewModel()
            .inviteDetail(mInviteId)
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = { result ->
                    val obj = JSONObject(result)

                    mShopId = obj.optNotNull("enterpriseId")
                    mInviteId = obj.optNotNull("id")

                    mBinding
                        .apply {
                            inviteTitle.text = obj.optNotNull("name")
                            inviteMemo.setText(obj.optNotNull("memo"))
                        }

                    /*-------- 空桶信息 --------*/
                    val objBarrel = obj.optJSONArray("creditBarrels") ?: JSONArray()
                    mEditList.clear()
                    mEditList.addItems(
                        JsonUtil.toList(
                            objBarrel.toString(),
                            DispatchBucket::class.java
                        )
                    )

                    // 计算入库数
                    mEditList.forEach {
                        val count =
                            (it.returnQuantity.intValue
                                    - it.transQuantity.intValue)

                        if (count > 0) it.memo2 = count.toString()
                    }

                    mBarrelAdapter.notifyDataSetChanged()

                    /*-------- 烂桶信息 --------*/
                    val objRotten = obj.optJSONArray("creditSwaps") ?: JSONArray()
                    mRottenList.clear()
                    mRottenList.addItems(
                        JsonUtil.toList(
                            objRotten.toString(),
                            DispatchRotten::class.java
                        )
                    )
                    mRottenAdapter.notifyDataSetChanged()
                }
            )
    }

}